<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<title>Kinds</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
		<meta name="viewport" content="width=device-width initial-scale=1">
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<meta http-equiv="Content-Language" content="en-gb">

<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
MathJax = {
	tex: {
		inlineMath: '$', '$'], ['\\(', '\\)'
	},
	svg: {
		fontCache: 'global'
	}
};
</script>
<script type="text/javascript" id="MathJax-script" async
	src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js">
</script>

<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
		
	</head>
	<body class="commentary-font">
		<nav role="navigation">
		<h1><a href="../index.html"><img src="../docs-assets/Inform.png" height=72> </a></h1>
<ul><li><a href="../index.html">home</a></li>
</ul><h2>Compiler</h2><ul>
<li><a href="../structure.html">structure</a></li>
<li><a href="../inbuildn.html">inbuild</a></li>
<li><a href="../inform7n.html">inform7</a></li>
<li><a href="../intern.html">inter</a></li>
<li><a href="../services.html">services</a></li>
<li><a href="../secrets.html">secrets</a></li>
</ul><h2>Other Tools</h2><ul>
<li><a href="../inblorbn.html">inblorb</a></li>
<li><a href="../inform6.html">inform6</a></li>
<li><a href="../inpolicyn.html">inpolicy</a></li>
</ul><h2>Resources</h2><ul>
<li><a href="../extensions.html">extensions</a></li>
<li><a href="../kits.html">kits</a></li>
</ul><h2>Repository</h2><ul>
<li><a href="https://github.com/ganelson/inform"><img src="../docs-assets/github.png" height=0> github</a></li>
</ul><h2>Related Projects</h2><ul>
<li><a href="https://github.com/ganelson/inweb"><img src="../docs-assets/github.png" height=0> inweb</a></li>
<li><a href="https://github.com/ganelson/intest"><img src="../docs-assets/github.png" height=0> intest</a></li>
</ul>
		</nav>
		<main role="main">
		<!-- Weave of 'Kinds' generated by inweb -->
<div class="breadcrumbs">
    <ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../extensions.html">Kits</a></li><li><a href="index.html">BasicInformKit</a></li><li><b>Kinds</b></li></ul></div>
<p class="purpose">Kinds  An API for handling values within the Inform 7 system of kinds.</p>

<ul class="toc"><li><a href="knds.html#SP1">&#167;1. Strong and weak IDs</a></li><li><a href="knds.html#SP3">&#167;3. The kind metadata array</a></li><li><a href="knds.html#SP9">&#167;9. Non-standard enumerations</a></li><li><a href="knds.html#SP10">&#167;10. Kind-value pairs</a></li><li><a href="knds.html#SP14">&#167;14. The Pointer Value API</a></li></ul><hr class="tocbar">

<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. Strong and weak IDs.</b>Every kind has both a weak ID, like <span class="extract"><span class="extract-syntax">LIST_OF_TY</span></span>, and a strong ID, which is
a pointer to a small data structure: for instance, a pointer to the three
words <span class="extract"><span class="extract-syntax">LIST_OF_TY 1 NUMBER_TY</span></span> is the strong ID for "list of numbers".
</p>

<p class="commentary">This converts strong to weak, while preserving weak IDs as they are:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">KindWeakID</span><span class="plain-syntax"> </span><span class="identifier-syntax">strong_kind_id</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">strong_kind_id</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">strong_kind_id</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">BASE_KIND_HWM</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">strong_kind_id</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">strong_kind_id</span><span class="plain-syntax">--&gt;0;</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b>These can only work with a strong ID: the call <span class="extract"><span class="extract-syntax">KindConstructorArity(LIST_OF_TY)</span></span>
does not return 2.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">KindConstructorArity</span><span class="plain-syntax"> </span><span class="identifier-syntax">strong_kind_id</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">strong_kind_id</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">strong_kind_id</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">BASE_KIND_HWM</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">strong_kind_id</span><span class="plain-syntax">--&gt;1;</span>
<span class="plain-syntax">];</span>

<span class="plain-syntax">[ </span><span class="identifier-syntax">KindConstructorTerm</span><span class="plain-syntax"> </span><span class="identifier-syntax">strong_kind_id</span><span class="plain-syntax"> </span><span class="identifier-syntax">n</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">strong_kind_id</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">strong_kind_id</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">BASE_KIND_HWM</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">UNKNOWN_TY</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">strong_kind_id</span><span class="plain-syntax">--&gt;(2+</span><span class="identifier-syntax">n</span><span class="plain-syntax">);</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. The kind metadata array.</b>Weak IDs are used to read method functions and other details out of the
<span class="extract"><span class="extract-syntax">KindMetadata</span></span> array.
</p>

<p class="commentary">If <span class="extract"><span class="extract-syntax">w</span></span> is a weak ID, then the metadata on the kind is stored at
<span class="extract"><span class="extract-syntax">KindMetadata--&gt;(KindMetadata--&gt;w)</span></span> and consecutive words.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">ReadKindMetadata</span><span class="plain-syntax"> </span><span class="identifier-syntax">kind_id</span><span class="plain-syntax"> </span><span class="identifier-syntax">field</span><span class="plain-syntax"> </span><span class="identifier-syntax">x</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">kind_id</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">kind_id</span><span class="plain-syntax"> &gt;= </span><span class="identifier-syntax">BASE_KIND_HWM</span><span class="plain-syntax">)) </span><span class="identifier-syntax">kind_id</span><span class="plain-syntax"> = </span><span class="identifier-syntax">kind_id</span><span class="plain-syntax">--&gt;0;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">x</span><span class="plain-syntax"> = </span><span class="identifier-syntax">KindMetadata</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">kind_id</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">x</span><span class="plain-syntax"> ~= </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">KindMetadata</span><span class="plain-syntax">--&gt;(</span><span class="identifier-syntax">x</span><span class="plain-syntax">+</span><span class="identifier-syntax">field</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">x</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. </b>The fields in this array are numbered as follows. Note that kinds which do
not take pointer values provide only the first set of fields below; do not
look up <span class="extract"><span class="extract-syntax">CREATE_FN_KMF</span></span> and so on with <span class="extract"><span class="extract-syntax">ReadKindMetadata</span></span> for any kind which
does not conform to <span class="extract"><span class="extract-syntax">POINTER_VALUE_TY</span></span>.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="comment-syntax">Always present</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">WEAK_KIND_ID_KMF</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">SAY_FN_KMF</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">COMPARE_FN_KMF</span><span class="plain-syntax"> = </span><span class="constant-syntax">2</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">MAKE_DEFAULT_FN_KMF</span><span class="plain-syntax"> = </span><span class="constant-syntax">3</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">ENUMERATION_ARRAY_KMF</span><span class="plain-syntax"> = </span><span class="constant-syntax">4</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">DOMAIN_SIZE_KMF</span><span class="plain-syntax"> = </span><span class="constant-syntax">5</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">CONFORMANCE_KMF</span><span class="plain-syntax"> = </span><span class="constant-syntax">6</span><span class="plain-syntax">;</span>

<span class="comment-syntax">Present only for pointer-valued kinds</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">CREATE_FN_KMF</span><span class="plain-syntax"> = </span><span class="constant-syntax">7</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">CAST_FN_KMF</span><span class="plain-syntax"> = </span><span class="constant-syntax">8</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">COPY_FN_KMF</span><span class="plain-syntax"> = </span><span class="constant-syntax">9</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">COPY_SHORT_BLOCK_FN_KMF</span><span class="plain-syntax"> = </span><span class="constant-syntax">10</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">QUICK_COPY_FN_KMF</span><span class="plain-syntax"> = </span><span class="constant-syntax">11</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">DESTROY_FN_KMF</span><span class="plain-syntax"> = </span><span class="constant-syntax">12</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">MAKE_MUTABLE_FN_KMF</span><span class="plain-syntax"> = </span><span class="constant-syntax">13</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">HASH_FN_KMF</span><span class="plain-syntax"> = </span><span class="constant-syntax">14</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">SHORT_BLOCK_SIZE_KMF</span><span class="plain-syntax"> = </span><span class="constant-syntax">15</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">LONG_BLOCK_SIZE_KMF</span><span class="plain-syntax"> = </span><span class="constant-syntax">16</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">SERIALISE_FN_KMF</span><span class="plain-syntax"> = </span><span class="constant-syntax">17</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">UNSERIALISE_FN_KMF</span><span class="plain-syntax"> = </span><span class="constant-syntax">18</span><span class="plain-syntax">;</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. </b><span class="extract"><span class="extract-syntax">KindComparisonFunction(K)</span></span> returns either the address of a function to
perform a comparison between two values, or else 0 to signal that no
special sort of comparison is needed. (In which case signed numerical
comparison should be used.) The function <span class="extract"><span class="extract-syntax">F</span></span> may be used in a sorting algorithm,
so it must have no side-effects. <span class="extract"><span class="extract-syntax">F(x,y)</span></span> should return 1 if \(x&gt;y\),
0 if \(x=y\) and \(-1\) if \(x&lt;y\). Note that it is not permitted to return 0
unless the two values are genuinely equal.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">KindComparisonFunction</span><span class="plain-syntax"> </span><span class="identifier-syntax">kind_id</span><span class="plain-syntax"> </span><span class="identifier-syntax">fail</span><span class="plain-syntax"> </span><span class="identifier-syntax">s</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">ReadKindMetadata</span><span class="plain-syntax">(</span><span class="identifier-syntax">kind_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">COMPARE_FN_KMF</span><span class="plain-syntax">);</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>&#167;6. </b>For kinds which are essentially infinite, the following returns 0.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">KindDomainSize</span><span class="plain-syntax"> </span><span class="identifier-syntax">kind_id</span><span class="plain-syntax"> </span><span class="identifier-syntax">fail</span><span class="plain-syntax"> </span><span class="identifier-syntax">s</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">ReadKindMetadata</span><span class="plain-syntax">(</span><span class="identifier-syntax">kind_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">DOMAIN_SIZE_KMF</span><span class="plain-syntax">);</span>
<span class="plain-syntax">];</span>

<span class="plain-syntax">[ </span><span class="identifier-syntax">KindEnumerationArray</span><span class="plain-syntax"> </span><span class="identifier-syntax">kind_id</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">ReadKindMetadata</span><span class="plain-syntax">(</span><span class="identifier-syntax">kind_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">ENUMERATION_ARRAY_KMF</span><span class="plain-syntax">);</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>&#167;7. </b><span class="extract"><span class="extract-syntax">KindDefaultValue(K)</span></span> returns the default value for kind <span class="extract"><span class="extract-syntax">K</span></span>: it's needed,
for instance, when increasing the size of a list of \(K\) to include new entries,
which have to be given some type-safe value to start out at.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">KindDefaultValue</span><span class="plain-syntax"> </span><span class="identifier-syntax">strong_kind_id</span><span class="plain-syntax"> </span><span class="identifier-syntax">mkdef_fn</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">mkdef_fn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ReadKindMetadata</span><span class="plain-syntax">(</span><span class="identifier-syntax">strong_kind_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">MAKE_DEFAULT_FN_KMF</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">mkdef_fn</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">mkdef_fn</span><span class="plain-syntax">(</span><span class="identifier-syntax">strong_kind_id</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>&#167;8. </b>True if and only if <span class="extract"><span class="extract-syntax">kid</span></span> is the (strong or weak) ID of a kind for which
values are pointers to blocks of data on the stack or heap.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">KindConformsTo_POINTER_VALUE_TY</span><span class="plain-syntax"> </span><span class="identifier-syntax">kind_id</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ReadKindMetadata</span><span class="plain-syntax">(</span><span class="identifier-syntax">kind_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">CONFORMANCE_KMF</span><span class="plain-syntax">));</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>&#167;9. Non-standard enumerations.</b>This is for enumerations whose values are scattered: say, for a kind where
the valid runtime values are 3, 15 and 421. Next after 3 is 15; previous
is 421, and so on.
</p>

<p class="commentary">The <span class="extract"><span class="extract-syntax">instances</span></span> array supplied has the extent in word 0, which is in effect
the number of valid instances. This is guaranteed to be at least 1.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">NextEnumVal</span><span class="plain-syntax"> </span><span class="identifier-syntax">inst</span><span class="plain-syntax"> </span><span class="identifier-syntax">instances</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> </span><span class="identifier-syntax">count</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">count</span><span class="plain-syntax"> = </span><span class="identifier-syntax">instances</span><span class="plain-syntax">--&gt;0;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">=1: </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;=</span><span class="identifier-syntax">count</span><span class="plain-syntax">: </span><span class="identifier-syntax">i</span><span class="plain-syntax">++)</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">instances</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">i</span><span class="plain-syntax"> == </span><span class="identifier-syntax">inst</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">instances</span><span class="plain-syntax">--&gt;(</span><span class="identifier-syntax">i</span><span class="plain-syntax">%</span><span class="identifier-syntax">count</span><span class="plain-syntax"> + </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">instances</span><span class="plain-syntax">--&gt;1; </span><span class="comment-syntax">Should not ever happen</span>
<span class="plain-syntax">];</span>

<span class="plain-syntax">[ </span><span class="identifier-syntax">PrevEnumVal</span><span class="plain-syntax"> </span><span class="identifier-syntax">inst</span><span class="plain-syntax"> </span><span class="identifier-syntax">instances</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> </span><span class="identifier-syntax">count</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">count</span><span class="plain-syntax"> = </span><span class="identifier-syntax">instances</span><span class="plain-syntax">--&gt;0;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">=1: </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;=</span><span class="identifier-syntax">count</span><span class="plain-syntax">: </span><span class="identifier-syntax">i</span><span class="plain-syntax">++)</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">instances</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">i</span><span class="plain-syntax"> == </span><span class="identifier-syntax">inst</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">instances</span><span class="plain-syntax">--&gt;((</span><span class="identifier-syntax">i</span><span class="plain-syntax">+</span><span class="identifier-syntax">count</span><span class="plain-syntax">-2)%</span><span class="identifier-syntax">count</span><span class="plain-syntax"> + </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">instances</span><span class="plain-syntax">--&gt;1; </span><span class="comment-syntax">Should not ever happen</span>
<span class="plain-syntax">];</span>

<span class="plain-syntax">[ </span><span class="identifier-syntax">RandomEnumVal</span><span class="plain-syntax"> </span><span class="identifier-syntax">instances</span><span class="plain-syntax"> </span><span class="identifier-syntax">a</span><span class="plain-syntax"> </span><span class="identifier-syntax">b</span><span class="plain-syntax"> </span><span class="identifier-syntax">count</span><span class="plain-syntax"> </span><span class="identifier-syntax">a_index</span><span class="plain-syntax"> </span><span class="identifier-syntax">b_index</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">count</span><span class="plain-syntax"> = </span><span class="identifier-syntax">instances</span><span class="plain-syntax">--&gt;0;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">a</span><span class="plain-syntax"> == </span><span class="identifier-syntax">b</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">a</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">instances</span><span class="plain-syntax">--&gt;(</span><span class="reserved-syntax">random</span><span class="plain-syntax">(</span><span class="identifier-syntax">count</span><span class="plain-syntax">));</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">a</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">: </span><span class="identifier-syntax">c</span><span class="plain-syntax"> &lt;= </span><span class="identifier-syntax">count</span><span class="plain-syntax">: </span><span class="identifier-syntax">c</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">instances</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="identifier-syntax">a</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">a_index</span><span class="plain-syntax"> = </span><span class="identifier-syntax">c</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">instances</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="identifier-syntax">b</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">b_index</span><span class="plain-syntax"> = </span><span class="identifier-syntax">c</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">a_index</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">b_index</span><span class="plain-syntax">) { </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><span class="identifier-syntax">a_index</span><span class="plain-syntax">; </span><span class="identifier-syntax">a_index</span><span class="plain-syntax"> = </span><span class="identifier-syntax">b_index</span><span class="plain-syntax">; </span><span class="identifier-syntax">b_index</span><span class="plain-syntax"> = </span><span class="identifier-syntax">c</span><span class="plain-syntax">; }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">instances</span><span class="plain-syntax">--&gt;(</span><span class="identifier-syntax">a_index</span><span class="plain-syntax"> + </span><span class="reserved-syntax">random</span><span class="plain-syntax">(</span><span class="identifier-syntax">b_index</span><span class="plain-syntax"> - </span><span class="identifier-syntax">a_index</span><span class="plain-syntax"> + </span><span class="constant-syntax">1</span><span class="plain-syntax">) - </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
<span class="plain-syntax">];</span>

<span class="plain-syntax">[ </span><span class="identifier-syntax">IndexOfEnumVal</span><span class="plain-syntax"> </span><span class="identifier-syntax">instances</span><span class="plain-syntax"> </span><span class="identifier-syntax">a</span><span class="plain-syntax"> </span><span class="identifier-syntax">count</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">count</span><span class="plain-syntax"> = </span><span class="identifier-syntax">instances</span><span class="plain-syntax">--&gt;0;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">: </span><span class="identifier-syntax">c</span><span class="plain-syntax"> &lt;= </span><span class="identifier-syntax">count</span><span class="plain-syntax">: </span><span class="identifier-syntax">c</span><span class="plain-syntax">++)</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">instances</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="identifier-syntax">a</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>&#167;10. Kind-value pairs.</b>Just a few functions can be performed on any value of any kind, but the
functions in question have to be told the kind, since (unless the value is
a pointer) there will be no way to deduce this.
</p>

<p class="commentary"><span class="extract"><span class="extract-syntax">SayKindValuePair(K, V)</span></span> prints out the value <span class="extract"><span class="extract-syntax">V</span></span> on the assumption that
it belongs to the kind <span class="extract"><span class="extract-syntax">K</span></span>.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">SayKindValuePair</span><span class="plain-syntax"> </span><span class="identifier-syntax">kind_id</span><span class="plain-syntax"> </span><span class="identifier-syntax">value</span><span class="plain-syntax"> </span><span class="identifier-syntax">say_fn</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">say_fn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ReadKindMetadata</span><span class="plain-syntax">(</span><span class="identifier-syntax">kind_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">SAY_FN_KMF</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">say_fn</span><span class="plain-syntax">) </span><span class="identifier-syntax">say_fn</span><span class="plain-syntax">(</span><span class="identifier-syntax">value</span><span class="plain-syntax">); </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="identifier-syntax">value</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>&#167;11. </b>And here is a general comparison.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">CompareKindValuePairs</span><span class="plain-syntax"> </span><span class="identifier-syntax">k1</span><span class="plain-syntax"> </span><span class="identifier-syntax">v1</span><span class="plain-syntax"> </span><span class="identifier-syntax">k2</span><span class="plain-syntax"> </span><span class="identifier-syntax">v2</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">cmp_fn</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">k1</span><span class="plain-syntax"> ~= </span><span class="identifier-syntax">k2</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">k1</span><span class="plain-syntax">-</span><span class="identifier-syntax">k2</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">cmp_fn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ReadKindMetadata</span><span class="plain-syntax">(</span><span class="identifier-syntax">k1</span><span class="plain-syntax">, </span><span class="identifier-syntax">COMPARE_FN_KMF</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cmp_fn</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">cmp_fn</span><span class="plain-syntax">(</span><span class="identifier-syntax">v1</span><span class="plain-syntax">, </span><span class="identifier-syntax">v2</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">v1</span><span class="plain-syntax">-</span><span class="identifier-syntax">v2</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>&#167;12. </b>Given a value of any kind, assign it a hash code which fits in a single
virtual machine word, maximizing the chances that two different values
will have different hash codes.
</p>

<p class="commentary">If the value can be stored in a single word already, it can be its own hash
code. Otherwise, we ask its hash function to return one for us. Whatever this
does, it must at minimum have the property that two equivalent values (for which
the kind's comparison function returns 0) produce the same hash.
</p>

<p class="commentary">Note that if a pointer-valued kind provides no hash function, all of its values
are given the hash code 0. This will force pairs of such values to be compared
the hard way, but we have nothing better to offer. To return <span class="extract"><span class="extract-syntax">value</span></span> would be
an error, since it would mean that a value and its duplicate would have
different hash codes despite being equal.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">HashKindValuePair</span><span class="plain-syntax"> </span><span class="identifier-syntax">kind_id</span><span class="plain-syntax"> </span><span class="identifier-syntax">value</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">hash_function</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">KindConformsTo_POINTER_VALUE_TY</span><span class="plain-syntax">(</span><span class="identifier-syntax">kind_id</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">value</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">hash_function</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ReadKindMetadata</span><span class="plain-syntax">(</span><span class="identifier-syntax">kind_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">HASH_FN_KMF</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">hash_function</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">hash_function</span><span class="plain-syntax">(</span><span class="identifier-syntax">value</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">value</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP13" class="paragraph-anchor"></a><b>&#167;13. </b>Some values can be written to external files and shared with other projects:
others cannot. The following routines abstract that.
</p>

<p class="commentary">If <span class="extract"><span class="extract-syntax">ch</span></span> is \(-1\), then the unserialise function returns <span class="extract"><span class="extract-syntax">true</span></span> or <span class="extract"><span class="extract-syntax">false</span></span>
according to whether it is possible to read data from an auxiliary file <span class="extract"><span class="extract-syntax">auxf</span></span>
into the block value <span class="extract"><span class="extract-syntax">bv</span></span>. If <span class="extract"><span class="extract-syntax">ch</span></span> is any other value, then the routine should
do exactly that, taking <span class="extract"><span class="extract-syntax">ch</span></span> to be the first character of the text read from the
file which makes up the serialised form of the data.
</p>

<p class="commentary">Serialising is simpler because, strictly speaking, it doesn't write to a file at
all: it simply prints a serialised form of the data in <span class="extract"><span class="extract-syntax">bv</span></span> to the output
stream. Since it is called only when that output stream has been redirected to
an auxiliary file, and since the serialised form would often be illegible on
screen, it seems reasonable to call it a file input-output function just the
same. The serialise function should return <span class="extract"><span class="extract-syntax">true</span></span> or <span class="extract"><span class="extract-syntax">false</span></span> according to
whether it was able to write the data.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">SerialiseKindValuePair</span><span class="plain-syntax"> </span><span class="identifier-syntax">kind_id</span><span class="plain-syntax"> </span><span class="identifier-syntax">value</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">serialise_function</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">KindConformsTo_POINTER_VALUE_TY</span><span class="plain-syntax">(</span><span class="identifier-syntax">kind_id</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">serialise_function</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ReadKindMetadata</span><span class="plain-syntax">(</span><span class="identifier-syntax">kind_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">SERIALISE_FN_KMF</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">serialise_function</span><span class="plain-syntax">) </span><span class="identifier-syntax">serialise_function</span><span class="plain-syntax">(</span><span class="identifier-syntax">value</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="identifier-syntax">value</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="identifier-syntax">value</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">];</span>

<span class="plain-syntax">[ </span><span class="identifier-syntax">UnserialiseKindValuePair</span><span class="plain-syntax"> </span><span class="identifier-syntax">kind_id</span><span class="plain-syntax"> </span><span class="identifier-syntax">value</span><span class="plain-syntax"> </span><span class="identifier-syntax">auxf</span><span class="plain-syntax"> </span><span class="identifier-syntax">ch</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">unserialise_function</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">KindConformsTo_POINTER_VALUE_TY</span><span class="plain-syntax">(</span><span class="identifier-syntax">kind_id</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">unserialise_function</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ReadKindMetadata</span><span class="plain-syntax">(</span><span class="identifier-syntax">kind_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">UNSERIALISE_FN_KMF</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">unserialise_function</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">unserialise_function</span><span class="plain-syntax">(</span><span class="identifier-syntax">value</span><span class="plain-syntax">, </span><span class="identifier-syntax">auxf</span><span class="plain-syntax">, </span><span class="identifier-syntax">ch</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP14" class="paragraph-anchor"></a><b>&#167;14. The Pointer Value API.</b>This sits on top of the BlkValue API, but whereas the latter can be used for
many potential purposes, the PV functions are strictly for dealing with
values of kinds conforming to POINTER_VALUE_TY.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">DestroyPV</span><span class="plain-syntax"> = </span><span class="identifier-syntax">BlkValueFree</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">CreatePV</span><span class="plain-syntax"> = </span><span class="identifier-syntax">BlkValueCreate</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">CopyPV</span><span class="plain-syntax"> = </span><span class="identifier-syntax">BlkValueCopy</span><span class="plain-syntax">;</span>

<span class="plain-syntax">[ </span><span class="identifier-syntax">CopyPVIfExists</span><span class="plain-syntax"> </span><span class="identifier-syntax">to_bv</span><span class="plain-syntax"> </span><span class="identifier-syntax">from_bv</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">from_bv</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">BlkValueCopy</span><span class="plain-syntax">(</span><span class="identifier-syntax">to_bv</span><span class="plain-syntax">, </span><span class="identifier-syntax">from_bv</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">to_bv</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>

<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">CastPV</span><span class="plain-syntax"> = </span><span class="identifier-syntax">BlkValueCast</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">ComparePV</span><span class="plain-syntax"> = </span><span class="identifier-syntax">BlkValueCompare</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">WeakKindOfPV</span><span class="plain-syntax"> = </span><span class="identifier-syntax">BlkValueWeakKind</span><span class="plain-syntax">;</span>

<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">PVField</span><span class="plain-syntax"> = </span><span class="identifier-syntax">BlkValueReadSB</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">WritePVField</span><span class="plain-syntax"> = </span><span class="identifier-syntax">BlkValueWriteSB</span><span class="plain-syntax">;</span>

<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">InitialisePVLongBlockField</span><span class="plain-syntax"> = </span><span class="identifier-syntax">BlkValueWriteLB</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">PVLongBlockField</span><span class="plain-syntax"> = </span><span class="identifier-syntax">BlkValueReadLB</span><span class="plain-syntax">;</span>

<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">SBONLYPV_FIELDS</span><span class="plain-syntax"> = </span><span class="constant-syntax">2</span><span class="plain-syntax">;</span>

<span class="plain-syntax">[ </span><span class="identifier-syntax">CreatePVShortBlock</span><span class="plain-syntax"> </span><span class="identifier-syntax">sb_address</span><span class="plain-syntax"> </span><span class="identifier-syntax">kind_id</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">short_block</span><span class="plain-syntax"> </span><span class="identifier-syntax">size</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">size</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ReadKindMetadata</span><span class="plain-syntax">(</span><span class="identifier-syntax">kind_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">SHORT_BLOCK_SIZE_KMF</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">short_block</span><span class="plain-syntax"> = </span><span class="identifier-syntax">BlkValueCreateSB</span><span class="plain-syntax">(</span><span class="identifier-syntax">sb_address</span><span class="plain-syntax">, </span><span class="identifier-syntax">size</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ReadKindMetadata</span><span class="plain-syntax">(</span><span class="identifier-syntax">kind_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">LONG_BLOCK_SIZE_KMF</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">short_block</span><span class="plain-syntax">--&gt;0 = </span><span class="identifier-syntax">BLK_BVBITMAP_SBONLY</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">short_block</span><span class="plain-syntax">--&gt;1 = </span><span class="identifier-syntax">kind_id</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">short_block</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>

<span class="plain-syntax">[ </span><span class="identifier-syntax">CreatePVLongBlock</span><span class="plain-syntax"> </span><span class="identifier-syntax">kind_id</span><span class="plain-syntax"> </span><span class="identifier-syntax">size</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">size</span><span class="plain-syntax"> &lt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">size</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ReadKindMetadata</span><span class="plain-syntax">(</span><span class="identifier-syntax">kind_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">LONG_BLOCK_SIZE_KMF</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">size</span><span class="plain-syntax"> </span><span class="reserved-syntax">ofclass</span><span class="plain-syntax"> </span><span class="identifier-syntax">Routine</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">BlkValueError</span><span class="plain-syntax">(</span><span class="string-syntax">"CreatePVLongBlock needs a size"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">size</span><span class="plain-syntax"> = </span><span class="constant-syntax">8</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">BlkValueCreateLB</span><span class="plain-syntax">(</span><span class="identifier-syntax">size</span><span class="plain-syntax">, </span><span class="identifier-syntax">kind_id</span><span class="plain-syntax">);</span>
<span class="plain-syntax">];</span>

<span class="plain-syntax">[ </span><span class="identifier-syntax">CreatePVLongBlockFlexible</span><span class="plain-syntax"> </span><span class="identifier-syntax">kind_id</span><span class="plain-syntax"> </span><span class="identifier-syntax">size</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">size</span><span class="plain-syntax"> &lt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">BlkValueError</span><span class="plain-syntax">(</span><span class="string-syntax">"CreatePVLongBlockFlexible needs a size"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">size</span><span class="plain-syntax"> = </span><span class="constant-syntax">8</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">BlkValueCreateMultipleLB</span><span class="plain-syntax">(</span><span class="identifier-syntax">size</span><span class="plain-syntax">, </span><span class="identifier-syntax">kind_id</span><span class="plain-syntax">);</span>
<span class="plain-syntax">];</span>

<span class="plain-syntax">[ </span><span class="identifier-syntax">KindOfShortBlockOnlyPV</span><span class="plain-syntax"> </span><span class="identifier-syntax">bv</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">bv</span><span class="plain-syntax">--&gt;1;</span>
<span class="plain-syntax">];</span>

<span class="plain-syntax">[ </span><span class="identifier-syntax">ShortBlockOnlyPVFlags</span><span class="plain-syntax"> </span><span class="identifier-syntax">bv</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> (</span><span class="identifier-syntax">bv</span><span class="plain-syntax">--&gt;0) &amp; </span><span class="identifier-syntax">BLK_BVUSERBITMAP</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>
<span class="plain-syntax">[ </span><span class="identifier-syntax">WriteShortBlockOnlyPVFlags</span><span class="plain-syntax"> </span><span class="identifier-syntax">bv</span><span class="plain-syntax"> </span><span class="identifier-syntax">flags</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">bv</span><span class="plain-syntax">--&gt;0 = ((</span><span class="identifier-syntax">bv</span><span class="plain-syntax">--&gt;0) &amp; </span><span class="identifier-syntax">BLK_BVBITMAP_USERBITMAPMASK</span><span class="plain-syntax">) + (</span><span class="identifier-syntax">flags</span><span class="plain-syntax"> &amp; </span><span class="identifier-syntax">BLK_BVUSERBITMAP</span><span class="plain-syntax">);</span>
<span class="plain-syntax">];</span>

<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">CopyPVShortBlock</span><span class="plain-syntax"> = </span><span class="identifier-syntax">BlkValueCopySB</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">CopyPVRawData</span><span class="plain-syntax"> = </span><span class="identifier-syntax">BlkValueCopyRawLongBlock</span><span class="plain-syntax">;</span>

<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">PVFieldCapacity</span><span class="plain-syntax"> = </span><span class="identifier-syntax">BlkValueLBCapacity</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">SetPVFieldCapacity</span><span class="plain-syntax"> = </span><span class="identifier-syntax">BlkValueSetLBCapacity</span><span class="plain-syntax">;</span>

<span class="plain-syntax">[ </span><span class="identifier-syntax">WritePVFieldsFromByteArray</span><span class="plain-syntax"> </span><span class="identifier-syntax">to_bv</span><span class="plain-syntax"> </span><span class="identifier-syntax">from_array</span><span class="plain-syntax"> </span><span class="identifier-syntax">no_entries_to_copy</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">BlkValueMassCopyFromArray</span><span class="plain-syntax">(</span><span class="identifier-syntax">to_bv</span><span class="plain-syntax">, </span><span class="identifier-syntax">from_array</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">, </span><span class="identifier-syntax">no_entries_to_copy</span><span class="plain-syntax">);</span>
<span class="plain-syntax">];</span>

<span class="plain-syntax">[ </span><span class="identifier-syntax">WritePVFieldsFromWordArray</span><span class="plain-syntax"> </span><span class="identifier-syntax">to_bv</span><span class="plain-syntax"> </span><span class="identifier-syntax">from_array</span><span class="plain-syntax"> </span><span class="identifier-syntax">no_entries_to_copy</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">BlkValueMassCopyFromArray</span><span class="plain-syntax">(</span><span class="identifier-syntax">to_bv</span><span class="plain-syntax">, </span><span class="identifier-syntax">from_array</span><span class="plain-syntax">, </span><span class="constant-syntax">4</span><span class="plain-syntax">, </span><span class="identifier-syntax">no_entries_to_copy</span><span class="plain-syntax">);</span>
<span class="plain-syntax">];</span>

<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">DestroyPVFromStack</span><span class="plain-syntax"> = </span><span class="identifier-syntax">BlkValueFreeOnStack</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">CreatePVOnStack</span><span class="plain-syntax"> = </span><span class="identifier-syntax">BlkValueCreateOnStack</span><span class="plain-syntax">;</span>
</pre>
<nav role="progress"><div class="progresscontainer">
    <ul class="progressbar"><li class="progressprev"><a href="blckv.html">&#10094;</a></li><li class="progresssection"><a href="dfntn.html">dfntn</a></li><li class="progresssection"><a href="strtp.html">strtp</a></li><li class="progresssection"><a href="utlts.html">utlts</a></li><li class="progresssection"><a href="prgrp.html">prgrp</a></li><li class="progresssection"><a href="mthmt.html">mthmt</a></li><li class="progresssection"><a href="srt.html">srt</a></li><li class="progresssection"><a href="tbls.html">tbls</a></li><li class="progresssection"><a href="mstck.html">mstck</a></li><li class="progresssection"><a href="rlbks.html">rlbks</a></li><li class="progresssection"><a href="actvt.html">actvt</a></li><li class="progresssection"><a href="prntn.html">prntn</a></li><li class="progresssection"><a href="flx.html">flx</a></li><li class="progresssection"><a href="blckv.html">blckv</a></li><li class="progresscurrent">knds</li><li class="progresssection"><a href="txt.html">txt</a></li><li class="progresssection"><a href="chr.html">chr</a></li><li class="progresssection"><a href="rgxp.html">rgxp</a></li><li class="progresssection"><a href="lsts.html">lsts</a></li><li class="progresssection"><a href="cmbnt.html">cmbnt</a></li><li class="progresssection"><a href="rltnk.html">rltnk</a></li><li class="progresssection"><a href="rltns.html">rltns</a></li><li class="progresssection"><a href="prprt.html">prprt</a></li><li class="progresssection"><a href="rtp.html">rtp</a></li><li class="progressnext"><a href="txt.html">&#10095;</a></li></ul></div>
</nav><!-- End of weave -->

		</main>
	</body>
</html>

